package 多线程;

import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Lock;

/**
 * 使用锁实现多线程按顺序打印ABC
 * 使用ReentrantLock确保线程安全，通过state变量控制打印顺序
 */
public class PrintABCUsingLock {
    private int times; // 每个字母需要打印的次数
    private int state; // 当前状态，用于控制打印顺序
    private Lock lock = new ReentrantLock(); // 可重入锁，用于线程同步

    /**
     * 构造函数
     * @param times 每个字母需要打印的次数
     */
    public PrintABCUsingLock(int times){
        this.times = times;
    }

    /**
     * 打印字母的方法
     * @param name 要打印的字母
     * @param targetNum 目标状态值，用于控制打印顺序
     * 当state % 3 == targetNum时，打印对应的字母
     */
    private void printLetter(String name, int targetNum){
        for(int i = 0; i < times; ){ // 循环打印指定次数
            lock.lock(); // 获取锁
            try {
                if(state % 3 == targetNum){ // 判断是否轮到当前线程打印
                    state++; // 更新状态
                    i++; // 更新打印次数
                    System.out.println(name); // 打印字母
                }
            } finally {
                lock.unlock(); // 释放锁
            }
        }
    }

    /**
     * 主函数：创建三个线程分别打印A、B、C
     * 使用Lambda表达式创建线程
     * 线程启动顺序：B -> A -> C
     */
    public static void main(String[] args) {
        PrintABCUsingLock loopThread = new PrintABCUsingLock(3); // 创建实例，每个字母打印3次
        
        // 创建打印B的线程
        new Thread(() -> {
            loopThread.printLetter("b", 1);
        }, "b").start();

        // 创建打印A的线程
        new Thread(() -> {
            loopThread.printLetter("a", 0);
        }, "a").start();

        // 创建打印C的线程
        new Thread(() -> {
            loopThread.printLetter("c", 2);
        }, "c").start();
    }
}
